/*!
 * iOS SDK
 *
 * Tencent is pleased to support the open source community by making
 * Hippy available.
 *
 * Copyright (C) 2019 THL A29 Limited, a Tencent company.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#import <QuartzCore/QuartzCore.h>

#import "HippyBridge.h"
#import "HippyDevLoadingView.h"
#import "HippyDefines.h"
#import "HippyUtils.h"
#import "HippyModalHostViewController.h"

#if HIPPY_DEV

static BOOL isEnabled = YES;
static CGFloat const HippyDevMsgViewHeight = 22.f;

@implementation HippyDevLoadingView {
    UIWindow *_window;
    UILabel *_label;
    NSDate *_showDate;
}

@synthesize bridge = _bridge;

HIPPY_EXPORT_MODULE()

+ (void)setEnabled:(BOOL)enabled {
    isEnabled = enabled;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (instancetype)init {
    // We're only overriding this to ensure the module gets created at startup
    // TODO (t11106126): Remove once we have more declarative control over module setup.
    return [super init];
}

- (void)setBridge:(HippyBridge *)bridge {
    _bridge = bridge;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hide) name:HippyJavaScriptDidLoadNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hide) name:HippyJavaScriptDidFailToLoadNotification object:nil];

    if (bridge.loading) {
        [self showWithURL:bridge.bundleURL];
    }
}

HIPPY_EXPORT_METHOD(showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(UIColor *)backgroundColor) {
    if (!isEnabled) {
        return;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        self->_showDate = [NSDate date];
        if (!self->_window && !HippyRunningInTestEnvironment()) {
            CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
            CGFloat viewHeight = HippyDevMsgViewHeight;
            if (@available(iOS 11.0, *)) {
                UIEdgeInsets safeAreaInsets = HippyKeyWindow().safeAreaInsets;
                if (safeAreaInsets.bottom > 0) {
                    //is iPhoneX
                    viewHeight += safeAreaInsets.top;
                }
            }
            self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenWidth, viewHeight)];
            self->_window.windowLevel = UIWindowLevelStatusBar + 1;
            // set a root VC so rotation is supported
            self->_window.rootViewController = [UIViewController new];
            
            self->_label = [[UILabel alloc] initWithFrame:self->_window.bounds];
            self->_label.font = [UIFont systemFontOfSize:12.0];
            self->_label.textAlignment = NSTextAlignmentCenter;
            
            [self->_window addSubview:self->_label];
        }
        
        self->_label.text = message;
        self->_label.textColor = color;
        self->_window.backgroundColor = backgroundColor;
        self->_window.hidden = NO;
    });
}

HIPPY_EXPORT_METHOD(hide) {
    if (!isEnabled) {
        return;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        const NSTimeInterval MIN_PRESENTED_TIME = 0.6;
        NSTimeInterval presentedTime = [[NSDate date] timeIntervalSinceDate:self->_showDate];
        NSTimeInterval delay = MAX(0, MIN_PRESENTED_TIME - presentedTime);
        CGRect windowFrame = self->_window.frame;
        [UIView animateWithDuration:0.25
                              delay:delay
                            options:0
                         animations:^{
            self->_window.frame = CGRectOffset(windowFrame, 0, -windowFrame.size.height);
        } completion:^(__unused BOOL finished) {
            self->_window.frame = windowFrame;
            self->_window.hidden = YES;
            self->_window = nil;
        }];
    });
}

- (void)showWithURL:(NSURL *)URL {
    UIColor *color;
    UIColor *backgroundColor;
    NSString *source;
    if (URL.fileURL) {
        color = [UIColor grayColor];
        backgroundColor = [UIColor blackColor];
        source = @"pre-bundled file";
    } else {
        color = [UIColor whiteColor];
        backgroundColor = [UIColor colorWithHue:1. / 3 saturation:1 brightness:.35 alpha:1];
        source = [NSString stringWithFormat:@"%@:%@", URL.host, URL.port];
    }

    [self showMessage:[NSString stringWithFormat:@"Loading from %@...", source] color:color backgroundColor:backgroundColor];
}

- (void)updateProgress:(HippyLoadingProgress *)progress {
    if (!progress) {
        return;
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        self->_label.text = [progress description];
    });
}

@end

#else

@implementation HippyDevLoadingView

+ (NSString *)moduleName {
    return nil;
}
+ (void)setEnabled:(__unused BOOL)enabled {
}
- (void)updateProgress:(__unused HippyLoadingProgress *)progress {
}

@end

#endif
